Skip to content

S08-09 Node-项目:mr-node-koa2-ejs-weibo

[TOC]

前置知识

EJS

概述

EJS(Embedded JavaScript templates):是一个简单高效的 JS 模板引擎。有如下作用:

  • HTML 中嵌入 JS 代码
  • 使用 JS 动态地生成最终的 HTML 页面。

它的主要作用是让开发者能够更容易地将数据(来自数据库、API等)和网页结构(HTML)分离开来,从而创建出动态的网页。


核心特点

  1. 语法简单

    EJS 的语法非常接近于纯 HTML。它使用特定的标签(如 <% %>)来嵌入 JS 逻辑,学习成本很低。

  2. 与 JS 无缝集成

    因为你直接在模板里写 JS,所以你可以使用 JS 的所有能力(变量、循环、条件判断、函数等)。

  3. 服务端渲染

    EJS 最常用于 Node.js 后端。服务器从数据库获取数据,然后通过 EJS 引擎将数据和模板结合,生成完整的 HTML 字符串,最后将这个字符串发送给客户端浏览器。这对 SEO(搜索引擎优化)非常友好。

语法标签

EJS 使用几种不同的标签来区分不同类型的 JS 代码:

执行控制流

<% %> - 执行控制流

用于嵌入JS 逻辑,如 if 条件判断for 循环等。这里的代码会被执行,但不会向输出结果中添加任何内容。

html
<% if (user) { %>
  <h1>Welcome, <%= user.name %></h1>
<% } else { %>
  <h1>Please log in</h1>
<% } %>
输出转移值

<%= %> - 输出转义的值

用于输出一个 JS 表达式的值到 HTML 中。

关键点:它会对 HTML 特殊字符(如 <, >, &, " 等)进行转义,以防止 XSS(跨站脚本)攻击。这是最常用的输出标签。

html
<p>Your username is: <%= username %></p>
<p>Your username is: <%= 1 + 1 %></p>
输出原始 HTML

<%- %> - 输出原始 HTML

用于输出未经转义的值。如果你的数据中包含 HTML 标签,并且你希望这些标签在浏览器中被渲染出来,而不是被显示为文本,就用这个标签。

注意:使用此标签时要确保数据来源是可信的,否则有 XSS 风险

html
<!-- 假设 article.content 是 '<p>This is a paragraph.</p>' -->
<div><%- article.content %></div>
<!-- 最终渲染结果将是一个真正的段落 -->
注释

<%# %> - 注释

模板内部的注释,不会出现在最终输出中。

html
<%# This is a comment, it will be ignored %>
包含其他模板

<%- include(...) %> - 包含其他模板

允许你将另一个 EJS 文件(如页头、页脚、导航栏)包含到当前模板中,实现代码复用。

html
<!DOCTYPE html>
<html>
<head>
    <%- include('partials/head') %>
</head>
<body>
    <%- include('partials/header') %>
    <main>
        <!-- 主要内容 -->
    </main>
    <%- include('partials/footer') %>
</body>
</html>

案例:Node 渲染

  • app.set()(name, value),Express 中用于设置应用程序配置的函数。

    常见用途

    1. 设置应用程序标题

      js
      app.set('title', '某个标题')
    2. 设置模板引擎

      js
      app.set('view engine', 'ejs')
    3. 指定视图文件所在目录

      js
      app.set('views', './views')
    4. 设置运行环境(生产/开发)

      js
      app.set('env', 'production')
    5. 启用或禁用功能

      布尔值配置项可以通过 app.set 启用或禁用。

      js
      app.set('case sensitive routing', true); // 区分大小写路由
  • res.render()(template, data?, options?),将一个 EJS 模板字符串和一个数据对象组合起来,编译并渲染成最终的 HTML 字符串

    options 选项:用于控制 EJS 引擎的多种行为。

    选项名类型默认值描述
    cacheBooleanfalse如果为 true,当使用 ejs.renderFile() 时会缓存编译后的函数。对于重复渲染相同的模板文件非常高效。(主要对 renderFile 有用)
    filenameStringnull模板的文件名。它有两个关键作用: 1. 用于缓存(当 cache: true 时)。 2. 用于解析 include() 中的相对路径。如果你想使用 include,这个选项几乎是必需的。
    rootStringnullviews 同义,设置项目的根目录,用于解析 include 的相对路径。Express 会默认设置这个。
    viewsArray[]一个目录路径数组,当使用 include 时,EJS 会从这些路径中查找模板。
    contextAnynull替换 data 对象,作为模板执行的根上下文。不常用。
    compileDebugBooleantrue (开发) false (生产)如果为 true,会在编译生成的函数中包含行号信息,用于产生更准确的错误堆栈。生产环境应设为 false 以提升性能。
    clientBooleanfalse返回一个独立的、可编译模板的函数,以便在浏览器端使用。
    delimiterString%用于修改 EJS 标签的分隔符。例如 delimiter: '?' 会让你使用 <? ... ?> 而不是 <% ... %>
    localsNameString'locals'用于存储在模板中使用的数据对象的变量名。通常不需要修改。
    rmWhitespaceBooleanfalse如果为 true,会移除所有可安全移除的空白字符,可以减小 HTML 输出的大小。
    outputFunctionNameString'print'clienttrue 时,用于设置编译函数中输出函数的名称。
    asyncBooleanfalse如果为 true,EJS 将支持在模板中使用 async/await 进行异步渲染。

1、服务端代码 (app.js)

js
const express = require('express');
const app = express();
const port = 3000;

// 1. 设置 EJS 为模板引擎
app.set('view engine', 'ejs');

app.get('/', (req, res) => {
  // 2. 准备要传递给模板的数据
  const data = {
    title: 'My EJS Page',
    user: { name: 'Alice' },
    items: ['Apple', 'Banana', 'Orange']
  };
    
  // 3. 渲染 'views/index.ejs' 模板,并传入数据
  res.render('index', data);
});

app.listen(port, () => {
  console.log(`Server running on port ${port}`);
});

2、主模板 (views/index.ejs)

html
<!DOCTYPE html>
<html>
<head>
    <title><%= title %></title>
</head>
<body>
    <%- include('partials/header') %>

    <h1>Hello, <%= user.name %>!</h1>

    <ul>
      <% items.forEach(function(item) { %>
        <li><%= item %></li>
      <% }); %>
    </ul>
</body>
</html>

mysql

sequelize

redis

jest

项目介绍

演示地址

环境搭建

eslint

inspect 调试

404/错误页

jwt

用户登录